package jmine.tec.test.metric.performance;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import com.thoughtworks.xstream.XStream;

/**
 * Gerar o arquivo xml especifico para o plugin para medir performance no jenkins.
 * 
 * @author bruno.ortiz
 */
public class XMLPerformanceGenerator {

    private static final String CABECALHO = "<?xml version=\"1.0\" encoding=\"";

    private XStream xstream = new XStream();

    private IReport report;

    /**
     * Construtor.
     * 
     * @param report Report do arquivo xml de performance.
     */
    public XMLPerformanceGenerator(IReport report) {
        this.report = report;
    }

    /**
     * Metodo que gera uma String no formato xml para criação do xml de performance.
     * 
     * @return String no formato xml para o xml de performance.
     */
    private String generateXMLPerformanceString() {
        this.xstream.processAnnotations(Report.class);
        return this.xstream.toXML(this.report);
    }

    /**
     * Gera a mensagem do xml com o conteudo proposto.
     * 
     * @param encoding o encoding da mensagem gerada.
     * @return a mensagem gerada.
     * @throws UnsupportedEncodingException caso o encoding parametrizado não seja suportado.
     */
    public String generateXMLDocument(String encoding) throws UnsupportedEncodingException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        this.printOutput(output, encoding);
        return output.toString();
    }

    /**
     * Gera o xml com o conteudo proposto no arquivo com path passado.
     * 
     * @param path path do arquivo a ser gerado.
     * @param encoding o encoding da mensagem gerada.
     * @return o arquivo gerado.
     * @throws FileNotFoundException path do arquivo incorreto.
     * @throws UnsupportedEncodingException caso o encoding parametrizado não seja suportado.
     */
    public File generateXMLDocument(String path, String encoding) throws FileNotFoundException, UnsupportedEncodingException {
        File file = new File(path);
        FileOutputStream output = new FileOutputStream(file);
        this.printOutput(output, encoding);
        return file;
    }

    /**
     * Imprime o conteudo do arquivo no {@link OutputStream}.
     * 
     * @param outputStream o output stream.
     * @param encoding o encoding em que o output será gerado.
     * @throws UnsupportedEncodingException caso o encoding parametrizado não seja suportado.
     */
    private void printOutput(OutputStream outputStream, String encoding) throws UnsupportedEncodingException {
        StringBuilder xml = new StringBuilder();
        xml.append(this.generateXMLPerformanceString());
        xml.insert(0, CABECALHO + encoding + "\"?>\n");
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, encoding);
        PrintWriter printer = new PrintWriter(writer);
        printer.print(xml.toString());
        printer.close();
    }

}
